#pragma once

namespace SL
{
    struct ComplementaryGrayWithPhaseShiftInputParam
    {
        float A;
        float B;
        int phaseShiftN;
        int grayCodeN;
        float cutoffPercentage;
        float phaseShiftCutoff;
        float minDistance;
        float maxDistance;
        int rowGap;
        int colGap;
        int imageHeight;
        int imageWidth;
        Size imageSize;
        int projectorHeight;
        int projectorWidth;
        Size projectorSize;
    };

    struct ComplementaryGrayWithPhaseShiftBiocularInputParam
    {
        float A;
        float B;
        int phaseShiftN;
        int grayCodeN;
        int imageHeight;
        int imageWidth;
        float cutoffPercentage;
        Size imageSize;
        ComplementaryGrayWithPhaseShiftInputParam complementaryGrayWithPhaseShiftInputParam;
    };

    struct GrayBrownWoOffsetParam
    {
        int grayCodeN;
    };

    struct GrayBrownWoOffsetCalibrateParam
    {
        int grayCodeColN;
        int grayCodeRowN;
        int cornerCols;
        int cornerRows;
        float squareHeight;
        float squareWidth;
        int imageHeight;
        int imageWidth;
        Size imageSize;
        int projectorHeight;
        int projectorWidth;
        Size projectorSize;
        int windowSize;
    };

    struct GrayBrownWOffsetCalibrateParam
    {
        int grayCodeColN;
        int grayCodeRowN;
        int cornerCols;
        int cornerRows;
        float squareHeight;
        float squareWidth;
        int imageHeight;
        int imageWidth;
        Size imageSize;
        int projectorHeight;
        int projectorWidth;
        Size projectorSize;
        int windowSize;
        bool enableOffset;
    };

    struct MonocularChessboardCalibrateParam
    {
        int imageHeight;
        int imageWidth;
        Size imageSize;
        int cornerCols;
        int cornerRows;
        float squareHeight;
        float squareWidth;
    };

    struct BiocularChessboardCalibrateParam
    {
        int imageHeight;
        int imageWidth;
        Size imageSize;
        int cornerCols;
        int cornerRows;
        float squareHeight;
        float squareWidth;
    };

    struct InputParamStruct
    {
        int projectorWidth;
        int projectorHeight;

        float b;
        float captureImageFindCornerScale;
        ComplementaryGrayWithPhaseShiftInputParam complementaryGrayWithPhaseShiftInputParam;
        ComplementaryGrayWithPhaseShiftBiocularInputParam complementaryGrayWithPhaseShiftBiocularInputParam;
        GrayBrownWoOffsetParam grayBrownWoOffsetParam;
        GrayBrownWoOffsetCalibrateParam grayBrownWoOffsetCalibrateParam;
        GrayBrownWOffsetCalibrateParam grayBrownWOffsetCalibrateParam;
        MonocularChessboardCalibrateParam monocularChessboardCalibrateParam;
        BiocularChessboardCalibrateParam biocularChessboardCalibrateParam;
        InputParamStruct()
        {
            b = 0.2f;
            captureImageFindCornerScale = 1.0f;
        }
    };

    class InputParam
    {

    public:
        static InputParam &getInstance()
        {
            static InputParam instance;
            return instance;
        }

        InputParamStruct &getInputParamStruct()
        {
            return this->_inputParamStruct;
        }

        void
        setInputParamStruct(InputParamStruct &inputParamStruct)
        {
            this->_inputParamStruct = inputParamStruct;
        }

    private:
        InputParam(){};
        InputParam(InputParam &) = delete;
        void operator=(InputParam const &) = delete;
        InputParamStruct _inputParamStruct;
    };

}